{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "5744d06a",
   "metadata": {},
   "source": [
    "------\n",
    "\n",
    "* 记录人：贺雪\n",
    "* 时间:2021-11-29\n",
    "* week14\n",
    "* 主要参考文档\n",
    "> 1.[Python官方文档](https://python.org/doc)   \n",
    "> 2.[博客--函数](https://)\n",
    "\n",
    "------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "289a3aec",
   "metadata": {},
   "source": [
    "# 本周内容\n",
    ">1.函数的定义    \n",
    ">2.如何使用函数   \n",
    ">3.函数的返回值   \n",
    ">4.使用注释改进文档   \n",
    ">5.传递任意数量的实参   \n",
    ">6.函数与模块"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0024e1f8",
   "metadata": {},
   "source": [
    "## 1.函数的定义\n",
    "------\n",
    "***\n",
    "def:定义函数的关键字   \n",
    "flb：函数名   \n",
    "(n)：定义函数的参数   \n",
    "\"\"\"\"\"\"：文档描述   \n",
    "代码块：   \n",
    "     a, b = 0, 1   \n",
    "     while a < n:   \n",
    "        print(a, end=' ')   \n",
    "         a, b = b, a+b   \n",
    "     print()   \n",
    "***\n",
    "------\n",
    "\n",
    "* 定义函数：\n",
    "\n",
    "> 1.写def:def 定义函数的第一步   \n",
    "> 2.写定义函数的名称：def function_name   \n",
    ">> 1.function_name 遵循变量名称定义的规则      \n",
    "> 3.函数名称后加上\"():\": def function_name(): ===> f(x) = 2x   \n",
    "\n",
    "* 书写函数体:\n",
    "\n",
    "> 1.函数的注释   \n",
    "> 2.写函数的具体操作（函数体）   \n",
    "> 3.注意：函数也是需要有tab键的缩进   \n",
    "\n",
    "* 使用函数(函数的调用):\n",
    "\n",
    "> 1.function_name()\n",
    "\n",
    "* 函数存在的意义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "11f38ff9",
   "metadata": {},
   "outputs": [],
   "source": [
    " def fib(n):    # write Fibonacci series up to n\n",
    "     \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "     a, b = 0, 1\n",
    "     while a < n:\n",
    "         print(a, end=' ')\n",
    "         a, b = b, a+b\n",
    "     print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "fd596ce6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 \n"
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "8478166a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function fib in module __main__:\n",
      "\n",
      "fib(n)\n",
      "    Print a Fibonacci series up to n.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(fib)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "72cd73fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 尝试： 写一个实现hello world的函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3ccc3858",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello():\n",
    "    \"\"\"打印hello world\"\"\"\n",
    "    print(\"hello world!\")\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "01f45140",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world!\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15527701",
   "metadata": {},
   "source": [
    "## 2.如何使用函数（课本实践149）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "4ec80fe4",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 思考函数存在的意义？\n",
    "# 1. 可以通过调用函数的方式实现某个功能，使用人不需要考虑函数代码内容\n",
    "# 2. 节省时间，提升应用的效率\n",
    "# 3. 函数一旦定义，就可按照一定的规则重复使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "6921f80a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义了一个名字叫\"search4vowels\"函数\n",
    "def search4vowels(word):\n",
    "    \"\"\"\n",
    "    打印文本中出现的元音字母\n",
    "    请输入你想要查询的文本内容\n",
    "    \"\"\"\n",
    "    vowels = set('aeiou')\n",
    "    found = vowels.intersection(set(word)) # 交集运算\n",
    "    print(found)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "1116bb9c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function search4vowels in module __main__:\n",
      "\n",
      "search4vowels(word)\n",
      "    打印文本中出现的元音字母\n",
      "    请输入你想要查询的文本内容\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(search4vowels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "9a4cd151",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'e'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"bgfhje\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "f6459d2d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a', 'e'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"ahdgvejkfgd\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b35936a8",
   "metadata": {},
   "source": [
    "----\n",
    "* 下面的方法是不是太重复了，主要原因是没有对重复功能的代码块有特殊的定义（如：名称，注释等）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "b136a977",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Provide a word to search for vowels:hello\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'e', 'o'}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowels = set('aeiou')\n",
    "word = input(\"Provide a word to search for vowels:\")\n",
    "found = vowels.intersection(set(word))\n",
    "found "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eea8b5a5",
   "metadata": {},
   "source": [
    "## 3.函数的参数\n",
    "\n",
    "* >font style=\"color:red> 注意：函数的参数可以没有，如果有参数，则如下（分为形式参数和实际参数）：</font>\n",
    "\n",
    ">1.形式参数（形参）  \n",
    ">>1.在定义过程中，函数的参数为形式参数  \n",
    ">>2.形式参数是虚拟的，不占用空间的   \n",
    "\n",
    ">2.实际参数（实参）  \n",
    ">>1. 调用函数过程中，函数的参数为实际参数  \n",
    ">>2.调用函数时，形式参数被分配空间，成为实际参数并应用起来  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "836b4734",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world!\n"
     ]
    }
   ],
   "source": [
    "# 函数是可以没有参数的\n",
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "d9adbf9d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义函数\n",
    "def greet_user(username):    \n",
    "    \"\"\"显示简单的问候语，输入你的名字\"\"\"    \n",
    "    print(\"hello,\"+ username.title()+\"!\")         \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "1b219091",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,Hexue!\n"
     ]
    }
   ],
   "source": [
    "#调用函数： username = \"hexue\"\n",
    "greet_user(\"hexue\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b35d77ee",
   "metadata": {},
   "source": [
    "* 当参数不止一个时：\n",
    ">1.位置参数(positional argument)     \n",
    ">>1.形式参数有多个值，如果实际参数直接赋值，要按照形式参数的先后顺序，这种方式称：位置参数赋值               \n",
    ">>2.在调用函数过程中需要考虑如下：    \n",
    ">>>1.考虑位置   \n",
    ">>>2.考虑个数 \n",
    "\n",
    ">2.关键字参数                                 \n",
    ">>1.在调用函数时使用，我们直接在实参中用赋值的方式去定义形参    \n",
    ">>2.不需要考虑顺序，因为赋值已经确定了形式参数的值  \n",
    "\n",
    ">3.默认参数                                             \n",
    ">>1.默认参数写在形式参数中(预计有大量的调用会使用到的值，可以预先设置)    \n",
    ">>2.默认参数存在的话，实际调用过程中可以省略赋值的过程   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "0c2dfc4d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 请注意，有两个参数\n",
    "def describe_pet(animal_type,pet_name):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My\" + animal_type + \"'s name is \"+pet_name.title() + \".\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "8ecd3249",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\",\"豆豆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "dde0d8e6",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "describe_pet() missing 1 required positional argument: 'pet_name'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-23-5208887e1c6b>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdescribe_pet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"cat\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: describe_pet() missing 1 required positional argument: 'pet_name'"
     ]
    }
   ],
   "source": [
    "describe_pet(\"cat\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "9c39039f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数\n",
    "describe_pet(animal_type=\"dog\",pet_name=\"豆豆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "913a6e20",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(pet_name=\"豆豆\",animal_type=\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "0ba28ef1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 默认参数(写在形式参数中的)\n",
    "def describe_pet(pet_name,animal_type=\"dog\"):\n",
    "    \"\"\"显示宠物信息，animal_type的默认值 'dog'\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My\" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "827c9203",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\",\"dog\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5ad9866",
   "metadata": {},
   "source": [
    "------\n",
    "* 实操和注意(参数部分)\n",
    "\n",
    ">1.如果想关键字参数和位置参数共同使用        \n",
    ">>1. positional argument follows keyword argument(位置参数需要放在关键字参数的前面)     \n",
    ">>2. 关键字放在末尾（均是关键字，不考虑顺序）\n",
    "\n",
    ">2.默认参数     \n",
    ">>1.non-default argument follows default argument(非默认参数需要放在默认参数前面)     \n",
    ">>2. 默认参数（均是默认参数，不考虑顺序）  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "2a76d631",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-8-c4aee12e4aad>, line 6)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-8-c4aee12e4aad>\"\u001b[1;36m, line \u001b[1;32m6\u001b[0m\n\u001b[1;33m    func_test(x=1,2)     #?\u001b[0m\n\u001b[1;37m                  ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "#eg1\n",
    "def func_test(x,y):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    \n",
    "func_test(x=1,2)     #?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "5cd70b1c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg2\n",
    "def func_test(x,y,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,1,z=3)     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "03e58a84",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "non-default argument follows default argument (<ipython-input-33-a3ef0e991634>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-33-a3ef0e991634>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    def func_test(x,y=4,z):\u001b[0m\n\u001b[1;37m                  ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m non-default argument follows default argument\n"
     ]
    }
   ],
   "source": [
    "#eg3\n",
    "def func_test(x,y=4,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,1,3)     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "d5ff3626",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "5\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg3\n",
    "def func_test(x,z,y=3):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,3,5)     "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
